package handler

import (
	"blog_go/internal/model"
	"blog_go/internal/service"
	"blog_go/pkg/helper/resp"
	"encoding/json"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

type UserHandler interface {
	QueryFollowUser(ctx *gin.Context)
	QueryUser(ctx *gin.Context)
	QueryAllUser(ctx *gin.Context)
	FollowUser(ctx *gin.Context)
	UpdateUserProfile(ctx *gin.Context)
	UpdatePwd(ctx *gin.Context)
	UpdateUserStatus(ctx *gin.Context)
	ResetUserPwd(ctx *gin.Context)
	RegisterUser(ctx *gin.Context)
	LoginUser(ctx *gin.Context)
	LoginAdmin(ctx *gin.Context)
	DelUser(ctx *gin.Context)
	Refresh(ctx *gin.Context)
}

type userHandler struct {
	*Handler
	userService service.UserService
}

func NewUserHandler(handler *Handler, userService service.UserService) UserHandler {
	return &userHandler{
		Handler:     handler,
		userService: userService,
	}
}

func (h *userHandler) Refresh(ctx *gin.Context) {
	var params struct {
		RefreshToken string `json:"refreshToken"`
	}

	if err := ctx.ShouldBind(&params); err != nil {
		resp.HandleError(ctx, http.StatusBadRequest, 1, "参数错误", nil)
		return
	}

	//解析refresh token
	claims, err := h.jwt.ParseToken(params.RefreshToken)
	if err != nil {
		resp.HandleError(ctx, http.StatusOK, 2006, "无效的refreshToken", nil)
		return
	}

	if claims.TokenType != "refresh" {
		resp.HandleError(ctx, http.StatusBadRequest, 1, "参数错误", nil)
		return
	}

	if claims.UserId == 0 {
		resp.HandleError(ctx, http.StatusBadRequest, 1, "token错误", nil)
		return
	}

	user, err := h.userService.RefreshToken(claims.UserId)
	if err != nil {
		resp.HandleError(ctx, http.StatusInternalServerError, 1, "token获取错误", nil)
		return
	}

	//生成access token
	accessToken, err := h.jwt.GetToken(user.Account, user.UserId, user.UserType, user.Status, "access", time.Now().Add(time.Hour*1))

	if err != nil {
		h.logger.Error("LoginUser GetToken failed", zap.Any("userId", claims.UserId), zap.Any("userType", claims.UserType), zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, "token获取错误", nil)
		return
	}

	resp.HandleLoginSuccess(ctx, nil, accessToken, "")
}

// 关注用户
func (h *userHandler) FollowUser(ctx *gin.Context) {
	var params struct {
		FollowerId int  `json:"followerId"`
		IsFollow   bool `json:"isFollow"`
	}

	userId := GetUserIdFromCtx(ctx)
	if userId == 0 {
		resp.HandleError(ctx, http.StatusBadRequest, 1, "token错误", nil)
		return
	}

	if err := ctx.ShouldBind(&params); err != nil {
		h.logger.Warn("FollowUser", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusBadRequest, 1, err.Error(), nil)
		return
	}

	h.logger.Info("FollowUser attempted", zap.Any("params", params))

	err := h.userService.FollowUser(userId, params.FollowerId, params.IsFollow)

	if err != nil {
		h.logger.Error("FollowUser failed", zap.Any("params", params), zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	resp.HandleSuccess(ctx, nil)
}

// 获取当前关注的用户信息
func (h *userHandler) QueryFollowUser(ctx *gin.Context) {
	var params struct {
		UserId int `form:"userId"`
	}

	if err := ctx.ShouldBind(&params); err != nil {
		h.logger.Warn("QueryFollowUser", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusBadRequest, 1, err.Error(), nil)
		return
	}

	h.logger.Info("QueryFollowUser attempted", zap.Any("params", params))

	data, err := h.userService.QueryFollowUser(params.UserId)

	if err != nil {
		h.logger.Error("QueryFollowUser failed", zap.Any("userId", params.UserId), zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	resp.HandleSuccess(ctx, data)
}

// 更新用户资料
func (h *userHandler) UpdateUserProfile(ctx *gin.Context) {
	files, _ := ctx.MultipartForm() // 获取fromdata的文件

	data, _ := ctx.GetPostForm("data") // 获取fromdata的文件

	var userParam model.User

	json.Unmarshal([]byte(data), &userParam)

	userId := GetUserIdFromCtx(ctx)
	if userId == 0 {
		resp.HandleError(ctx, http.StatusBadRequest, 1, "token错误", nil)
		return
	}

	//记录获取的用户
	h.logger.Info("UpdateUserProfile attempted")

	user, err := h.userService.UpdateUserProfile(userParam, files, userId)

	if err != nil {
		h.logger.Error("UpdateUserProfile failed", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	//返回成功状态码和用户信息
	resp.HandleSuccess(ctx, user)
}

// 禁用，解禁用户
func (h *userHandler) UpdateUserStatus(ctx *gin.Context) {
	var params struct {
		Status int `json:"status"`
		UserId int `json:"userId"`
	}

	if err := ctx.ShouldBind(&params); err != nil {
		h.logger.Warn("UpdateUserStatus", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusBadRequest, 1, err.Error(), nil)
		return
	}

	h.logger.Info("UpdateUserStatus attempted", zap.Any("params", params))

	err := h.userService.UpdateUserStatus(params.UserId, params.Status)

	if err != nil {
		h.logger.Error("UpdateUserStatus failed", zap.Any("params", params), zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	resp.HandleSuccess(ctx, nil)
}

// 修改用户，管理员密码
func (h *userHandler) UpdatePwd(ctx *gin.Context) {
	var user model.UserPwd

	if err := ctx.ShouldBind(&user); err != nil {
		h.logger.Warn("UpdatePwd", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusBadRequest, 1, err.Error(), nil)
		return
	}

	user.UserId = GetUserIdFromCtx(ctx)
	if user.UserId == 0 {
		resp.HandleError(ctx, http.StatusBadRequest, 1, "token错误", nil)
		return
	}

	h.logger.Info("UpdatePwd attempted", zap.Any("userId", user.UserId))

	err := h.userService.UpdatePwd(user)

	if err != nil {
		h.logger.Error("UpdatePwd failed", zap.Any("userId", user.UserId), zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	//返回成功状态码和用户信息
	resp.HandleSuccess(ctx, nil)
}

// 重置用户密码为123456
func (h *userHandler) ResetUserPwd(ctx *gin.Context) {
	var params struct {
		UserId int `json:"userId"`
	}

	if err := ctx.ShouldBind(&params); err != nil {
		h.logger.Warn("ResetUserPwd", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusBadRequest, 1, err.Error(), nil)
		return
	}

	h.logger.Info("ResetUserPwd attempted", zap.Any("userId", params.UserId))

	err := h.userService.ResetUserPwd(params.UserId)

	if err != nil {
		h.logger.Error("ResetUserPwd failed", zap.Any("userId", params.UserId), zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	//返回成功状态码和用户信息
	resp.HandleSuccess(ctx, nil)
}

// 用户登录
func (h *userHandler) LoginUser(ctx *gin.Context) {
	var loginUser model.LoginUser

	if err := ctx.ShouldBind(&loginUser); err != nil {
		h.logger.Warn("LoginUser", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusBadRequest, 1, err.Error(), nil)
		return
	}

	h.logger.Info("LoginUser attempted")

	user, err := h.userService.LoginUser(loginUser)

	if err != nil {
		h.logger.Error("LoginUser failed", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	if user == nil {
		resp.HandleError(ctx, http.StatusOK, 1, "账号或密码错误", nil)
		return
	}

	accessToken, err := h.jwt.GetToken(user.Account, user.UserId, user.UserType, user.Status, "access", time.Now().Add(time.Hour*24))

	if err != nil {
		h.logger.Error("LoginUser GetToken failed", zap.Any("userId", user.UserId), zap.Any("userType", user.UserType), zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, "token获取错误", nil)
		return
	}

	refreshToken, err := h.jwt.GetToken(user.Account, user.UserId, user.UserType, user.Status, "refresh", time.Now().Add(time.Hour*24*2))

	if err != nil {
		h.logger.Error("LoginUser GetToken failed", zap.Any("userId", user.UserId), zap.Any("userType", user.UserType), zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, "token获取错误", nil)
		return
	}

	resp.HandleLoginSuccess(ctx, user, accessToken, refreshToken)
}

// 管理员登录
func (h *userHandler) LoginAdmin(ctx *gin.Context) {
	var loginUser model.LoginUser

	if err := ctx.ShouldBind(&loginUser); err != nil {
		h.logger.Warn("LoginAdmin", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusBadRequest, 1, err.Error(), nil)
		return
	}

	h.logger.Info("LoginAdmin attempted")

	admin, err := h.userService.LoginAdmin(loginUser)

	if err != nil {
		h.logger.Error("LoginAdmin failed", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	if admin == nil {
		resp.HandleError(ctx, http.StatusOK, 1, "账号或密码错误", nil)
		return
	}

	accessToken, err := h.jwt.GetToken(admin.Account, admin.AdminId, admin.UserType, 0, "access", time.Now().Add(time.Hour*24))

	if err != nil {
		h.logger.Error("LoginAdmin  GetToken failed", zap.Any("adminId", admin.AdminId), zap.Any("userType", admin.UserType), zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, "token获取错误", nil)
		return
	}

	refreshToken, err := h.jwt.GetToken(admin.Account, admin.AdminId, admin.UserType, 0, "refresh", time.Now().Add(time.Hour*24*7))

	if err != nil {
		h.logger.Error("LoginAdmin  GetToken failed", zap.Any("adminId", admin.AdminId), zap.Any("userType", admin.UserType), zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, "token获取错误", nil)
		return
	}

	resp.HandleLoginSuccess(ctx, admin, accessToken, refreshToken)
}

// 用户注册
func (h *userHandler) RegisterUser(ctx *gin.Context) {
	var user model.User

	if err := ctx.ShouldBind(&user); err != nil {
		h.logger.Warn("RegisterUser", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusBadRequest, 1, err.Error(), nil)
		return
	}

	h.logger.Info("RegisterUser attempted")

	err := h.userService.RegisterUser(user)

	if err != nil {
		h.logger.Error("RegisterUser failed", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	//返回成功状态码和用户信息
	resp.HandleSuccess(ctx, nil)
}

// 查询用户
func (h *userHandler) QueryUser(ctx *gin.Context) {
	var params struct {
		UserId       int `form:"userId"`
		TargetUserId int `form:"targetUserId"`
	}

	if err := ctx.ShouldBind(&params); err != nil {
		h.logger.Warn("QueryUser", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusBadRequest, 1, err.Error(), nil)
		return
	}

	h.logger.Info("QueryUser attempted", zap.Any("params", params))

	data, err := h.userService.QueryUser(params.UserId, params.TargetUserId)

	if err != nil {
		h.logger.Error("QueryUser failed", zap.Any("targetUserId", params.TargetUserId), zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	//返回成功状态码和用户信息
	resp.HandleSuccess(ctx, data)
}

// 管理员查询所有用户
func (h *userHandler) QueryAllUser(ctx *gin.Context) {
	data, err := h.userService.QueryAllUser()

	if err != nil {
		h.logger.Error("QueryAllUser  failed", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	//返回成功状态码和用户信息
	resp.HandleSuccess(ctx, data)
}

// 删除用户
func (h *userHandler) DelUser(ctx *gin.Context) {
	var params struct {
		UserId int `json:"userId"`
	}

	if err := ctx.ShouldBind(&params); err != nil {
		h.logger.Warn("DelUser", zap.Any("error", err))
		resp.HandleError(ctx, http.StatusBadRequest, 1, err.Error(), nil)
		return
	}

	h.logger.Info("DelUser attempted", zap.Any("userId", params.UserId))

	err := h.userService.DelUser(params.UserId)

	if err != nil {
		h.logger.Error("DelUser  failed", zap.Any("userId", params.UserId), zap.Any("error", err))
		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
		return
	}

	resp.HandleSuccess(ctx, nil)
}
